﻿#pragma once
#include "yzrutil.h"
#include "DSP.h"
#include "RingBuffer.h"
#include "array/Arrays.h"
#include "array/Array.hpp"

namespace yzrilyzr_dsp{
	ECLASS(IIR, public DSP){
	public:
	yzrilyzr_array::DoubleArray aCoeff;
	yzrilyzr_array::DoubleArray bCoeff;
	RingBufferSample input;
	RingBufferSample output;
	IIR(){}
	IIR(std::shared_ptr<yzrilyzr_array::DoubleArray> *coeffs) : IIR(*coeffs[0], *coeffs[1]){
		delete[] coeffs;
	}
	IIR(u_index aLength, u_index bLength) :
		IIR(yzrilyzr_array::DoubleArray(aLength), yzrilyzr_array::DoubleArray(bLength)){}
	IIR(yzrilyzr_array::DoubleArray aCoeff, yzrilyzr_array::DoubleArray bCoeff) :
		aCoeff(aCoeff),
		bCoeff(bCoeff),
		input(bCoeff.length),
		output(aCoeff.length){}
	~IIR(){}
	u_sample procDsp(u_sample v)override{
		auto & inB=input;
		auto & outB=output;
		inB.write(v);
		u_sample y=0;
		double * aA=aCoeff._array;
		double * bA=bCoeff._array;
		u_index i, j;
		for(i=0, j=bCoeff.length;i < j;i++){
			y+=bA[i] * inB.getFromNewest(i);
		}
		for(i=0, j=aCoeff.length;i < j;i++){
			y-=aA[i] * outB.getFromNewest(i);
		}
		outB.write(y);
		return y;
	}
	void init(u_sample_rate sampleRate)override{}
	void resetMemory()override;
	std::shared_ptr<DSP> cloneDSP()override;
	void cloneParam(DSP * obj1)override;
	yzrilyzr_lang::String toString()const override;
	};
}